/*
 * Powered By cuichen
 * Since 2014 - 2015
 */
package com.seeyoui.kensite.framework.system.controller;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.seeyoui.kensite.common.base.controller.BaseController;
import com.seeyoui.kensite.common.base.domain.EasyUIDataGrid;
import com.seeyoui.kensite.common.constants.StringConstant;
import com.seeyoui.kensite.common.util.DateUtils;
import com.seeyoui.kensite.common.util.MD5;
import com.seeyoui.kensite.common.util.RequestResponseUtil;
import com.seeyoui.kensite.common.util.Result;
import com.seeyoui.kensite.common.util.StringUtils;
import com.seeyoui.kensite.common.util.excel.ExcelUtil;
import com.seeyoui.kensite.framework.plugin.log.domain.Log;
import com.seeyoui.kensite.framework.system.domain.SysDepartment;
import com.seeyoui.kensite.framework.system.domain.SysUser;
import com.seeyoui.kensite.framework.system.service.SysDepartmentService;
import com.seeyoui.kensite.framework.system.service.SysUserService;
import com.seeyoui.kensite.framework.system.util.UserUtils;

/**
 * @author cuichen
 * @version 1.0
 * @since 1.0
 */
@Controller
@RequestMapping(value = "sysUser")
public class SysUserController extends BaseController {

    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysDepartmentService sysDepartmentService;

    /**
     * 展示列表页面
     * 
     * @param modelMap
     * @param module
     * @return
     * @throws Exception
     */
    @RequiresPermissions("sysUser:view")
    @RequestMapping(value = "/{page}")
    public ModelAndView showSysDepartmentPageList(HttpSession session, HttpServletResponse response, HttpServletRequest request, ModelMap modelMap,
            @PathVariable String page) throws Exception {
        return new ModelAndView("framework/system/user/" + page, modelMap);
    }

    /**
     * 获取列表展示数据
     * 
     * @param modelMap
     * @param sysUser
     * @return
     * @throws Exception
     */
    @RequiresPermissions("sysUser:select")
    // @RequiresRoles("sys")
    @RequestMapping(value = "/list/data", method = RequestMethod.POST)
    @ResponseBody
    public Object listData(HttpSession session, HttpServletResponse response, HttpServletRequest request, ModelMap modelMap, SysUser sysUser)
            throws Exception {
        List<SysUser> sysUserList = sysUserService.findList(sysUser);
        int total = sysUserService.findTotal(sysUser);
        EasyUIDataGrid eudg = new EasyUIDataGrid();
        eudg.setRows(sysUserList);
        eudg.setTotal(String.valueOf(total));
        return eudg;
    }

    /**
     * 保存新增的数据
     * 
     * @param modelMap
     * @param sysUser
     * @return
     * @throws Exception
     */
    @RequiresPermissions("sysUser:insert")
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    @ResponseBody
    public String save(HttpSession session, HttpServletResponse response, HttpServletRequest request, ModelMap modelMap, SysUser sysUser)
            throws Exception {
        String resultInfo = sysUserService.save(sysUser);
        modelMap.put("message", resultInfo);
        RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.TRUE);
        return null;
    }

    /**
     * 保存修改的数据
     * 
     * @param modelMap
     * @param sysUser
     * @return
     * @throws Exception
     */
    @RequiresPermissions("sysUser:update")
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    @ResponseBody
    public String update(HttpSession session, HttpServletResponse response, HttpServletRequest request, ModelMap modelMap, SysUser sysUser)
            throws Exception {
        if (!beanValidator(modelMap, sysUser)) {
            RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
            return null;
        }
        sysUserService.update(sysUser);
        RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.TRUE);
        return null;
    }

    /**
     * 修改用户密码
     * 
     * @param modelMap
     * @param sysUser
     * @return
     * @throws Exception
     */
    @RequiresUser
    @RequestMapping(value = "/updatePassword", method = RequestMethod.POST)
    @ResponseBody
    public Object updatePassword(HttpSession session, HttpServletResponse response, HttpServletRequest request, ModelMap modelMap, SysUser sysUser)
            throws Exception {
        if (!beanValidator(modelMap, sysUser)) {
            RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
            return null;
        }
        sysUser.setPassword(MD5.md5(sysUser.getUserName() + sysUser.getPassword()));
        sysUserService.updatePassword(sysUser);
        RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.TRUE);
        return null;
    }

    /**
     * 跳转修改密码页面
     * 
     * @param request
     * @param model
     * @return
     */
    @RequestMapping("/goUpdatePassword")
    public String goUpdatePassword(HttpServletRequest request, Model model) {
        SysUser loginUser = UserUtils.getUser(request);
        model.addAttribute("userId", loginUser.getId());
        model.addAttribute("userName", loginUser.getUserName());
        return "partybuild/revisePassword";
    }

    /**
     * 检查原始密码
     * 
     * @param request
     * @param userName
     * @param password
     * @param id
     * @return
     */
    @RequestMapping(value = "/checkPassword", method = RequestMethod.POST)
    @ResponseBody
    public int checkPassword(HttpServletRequest request, String userName, String password, String id) {
        SysUser sysUser = sysUserService.findOne(id);
        if (MD5.md5(userName + password).equals(sysUser.getPassword())) {
            System.out.println("yes");
            return 1;
        } else {
            return 2;
        }
    }

    /**
     * 用户更换头像
     * 
     * @param id
     * @param headIcon
     * @return
     */
    @RequestMapping("/changeImage")
    @ResponseBody
    public Result changeImage(String id, String headIcon) {
        SysUser sysUser = sysUserService.findOne(id);
        sysUser.setHeadIcon(headIcon);
        sysUserService.update(sysUser);
        return Result.success("修改成功");
    }

    /**
     * 客户端修改密码
     * 
     * @param sysUser
     * @return
     */
    @RequestMapping(value = "/changePassword", method = RequestMethod.POST)
    public String changePassword(SysUser sysUser) {
        sysUser.setPassword(MD5.md5(sysUser.getUserName() + sysUser.getPassword()));
        sysUserService.updatePassword(sysUser);
        return "redirect:/cms/article/articleList?categoryId=9a076290eab144238ba33765a35fe7f8";
    }

    /**
     * app修改密码接口
     * 
     * @param request
     * @param oldPassword
     * @param newPassword
     * @return
     */
    @RequestMapping(value = "/updatePasswordMob", method = RequestMethod.POST)
    @ResponseBody
    public Result updatePasswordApp(HttpServletRequest request, String oldPassword, String newPassword) {
        String id = UserUtils.getUser(request).getId();
        if (StringUtils.isEmpty(id)) {
            return Result.failure("修改失败");
        }
        SysUser sysUser = sysUserService.findOne(id);
        if (MD5.md5(sysUser.getUserName() + oldPassword).equals(sysUser.getPassword())) {
            sysUser.setPassword(MD5.md5(sysUser.getUserName() + newPassword));
            sysUserService.updatePassword(sysUser);
            return Result.success("密码已修改");
        } else {
            return Result.failure("密码输入错误");
        }
    }

    /**
     * 跳转个人详情页面
     * 
     * @param request
     * @param model
     * @return
     */
    @RequestMapping("/goPersonalInformation")
    public String goPersonalInformation(HttpServletRequest request, Model model) {
        SysUser loginUser = UserUtils.getUser(request);
        model.addAttribute("loginUser", loginUser);
        return "partybuild/personalInformation";
    }

    /**
     * 个人信息接口
     * 
     * @param request
     * @return
     */
    @RequestMapping(value = "/personalInformation", method = RequestMethod.POST)
    @ResponseBody
    public Result findPersonalInformationById(HttpServletRequest request) {
        SysUser loginUser = UserUtils.getUser(request);
        if (loginUser != null) {
            return Result.success(loginUser);
        } else {
            return Result.failure("查询失败");
        }
    }

    /**
     * app登录记录接口(参数用户id) 根据用户id查询登录记录
     * 
     * @param request
     * @return
     */
    @RequestMapping(value = "/loginLog", method = RequestMethod.POST)
    @ResponseBody
    public Result findLoginLogById(HttpServletRequest request) {
        SysUser loginUser = UserUtils.getUser(request);
        List<Log> loginLogList = sysUserService.findLoginLogById(loginUser.getId());
        if (loginLogList.isEmpty()) {
            return Result.failure("没有数据");
        } else {
            return Result.success(loginLogList);
        }
    }

    /**
     * 修改账号状态
     * 
     * @param modelMap
     * @param sysUser
     * @return
     * @throws Exception
     */
    @RequiresPermissions("sysUser:update")
    @RequestMapping(value = "/updateState", method = RequestMethod.POST)
    @ResponseBody
    public String updateState(HttpSession session, HttpServletResponse response, HttpServletRequest request, ModelMap modelMap, SysUser sysUser)
            throws Exception {
        sysUserService.updateState(sysUser);
        RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.TRUE);
        return null;
    }

    /**
     * 初始化密码
     * 
     * @param modelMap
     * @param sysUser
     * @return
     * @throws Exception
     */
    @RequiresPermissions("sysUser:update")
    @RequestMapping(value = "/initPassword", method = RequestMethod.POST)
    @ResponseBody
    public String initPassword(HttpSession session, HttpServletResponse response, HttpServletRequest request, ModelMap modelMap, SysUser sysUser)
            throws Exception {
        sysUser = sysUserService.findOne(sysUser.getId());
        sysUser.setPassword(MD5.md5(sysUser.getUserName() + StringConstant.INIT_PASSWORD));
        sysUserService.updatePassword(sysUser);
        RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.TRUE);
        return null;
    }

    /**
     * 删除数据库
     * 
     * @param modelMap
     * @param sysUserId
     * @return
     * @throws Exception
     */
    @RequiresPermissions("sysUser:delete")
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    @ResponseBody
    public String delete(HttpSession session, HttpServletResponse response, HttpServletRequest request, ModelMap modelMap, String id)
            throws Exception {
        List<String> listId = Arrays.asList(id.split(","));
        sysUserService.delete(listId);
        RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.TRUE);
        return null;
    }

    /**
     * 验证用户名是否已被占用
     * 
     * @param modelMap
     * @param sysUserId
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/validateUserName")
    @ResponseBody
    public String validateUserName(HttpSession session, HttpServletResponse response, HttpServletRequest request, ModelMap modelMap, String userName)
            throws Exception {
        SysUser sysUserResult = sysUserService.findByUserName(userName);
        if (sysUserResult != null && (sysUserResult.getId() != null && !sysUserResult.getId().equals(""))) {
            RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
        }
        RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.TRUE);
        return null;
    }

    /**
     * 验证用户名是否已被占用
     * 
     * @param modelMap
     * @param sysUserId
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/validatePassWord")
    @ResponseBody
    public Object validatePassWord(HttpSession session, HttpServletResponse response, HttpServletRequest request, ModelMap modelMap, String userName,
            String passWord) throws Exception {
        SysUser sysUserResult = sysUserService.findByUserName(userName);
        if (sysUserResult != null && (sysUserResult.getId() != null && !sysUserResult.getId().equals(""))) {
            String newPassWord = MD5.md5(userName + passWord);
            if (newPassWord.equals(sysUserResult.getPassword())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 用户信息模版导入
     * 
     * @param session
     * @param response
     * @param request
     * @throws Exception
     */
    @RequiresPermissions("sysUser:insert")
    @RequestMapping(value = "/templateImport", method = RequestMethod.POST)
    @ResponseBody
    public String templateImport(@RequestParam(value = "file", required = false) MultipartFile file, HttpSession session,
            HttpServletResponse response, HttpServletRequest request, ModelMap modelMap) {
        List<SysUser> sysUserList = new ArrayList<SysUser>();// 定义接收所有解析到的用户信息对象
        List<Row> rowList = new ArrayList<Row>();// 定义行对象
        try {
            rowList = ExcelUtil.getRows(file, 1);
        } catch (Exception e) {
            modelMap.put("message", "解析模版出错");
            RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
            return null;
        }
        int dateNum = rowList.size();// 定义数据总条数
        int addNum = 0;// 定义新增数据条数
        int updateNum = 0;// 定义修改数据条数
        for (int i = 0; i < rowList.size(); i++) {
            Row row = rowList.get(i);
            /**
             * 获取所有列的值
             */
            String userName = ExcelUtil.getStringCellValue(row.getCell(0));// 获取用户名列的值
            String name = ExcelUtil.getStringCellValue(row.getCell(1));// 获取姓名列的值
            String departmentId = ExcelUtil.getStringCellValue(row.getCell(2));// 获取部门列的值
            String email = ExcelUtil.getStringCellValue(row.getCell(3));// 获取email列的值
            String phone = ExcelUtil.getStringCellValue(row.getCell(4));// 获取电话列的值
            String birthday = ExcelUtil.getStringCellValue(row.getCell(5));// 获取生日列的值
            String education = ExcelUtil.getStringCellValue(row.getCell(6));// 获取学历列的值
            String wechat = ExcelUtil.getStringCellValue(row.getCell(7));// 获取微信列的值
            String nation = ExcelUtil.getStringCellValue(row.getCell(8));// 获取民族列的值
            String nativePlace = ExcelUtil.getStringCellValue(row.getCell(9));// 获取籍贯列的值
            String joinPartyDate = ExcelUtil.getStringCellValue(row.getCell(10));// 获取入党时间列的值
            String employeeCode = ExcelUtil.getStringCellValue(row.getCell(11));// 获取编号列的值
            String summary = ExcelUtil.getStringCellValue(row.getCell(12));// 获取简介列的值

            /**
             * 非空校验
             */
            if (StringUtils.isEmpty(userName)) {
                modelMap.put("message", "导入文件中第" + (i + 2) + "行的用户名为空");
                RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                return null;
            }
            if (StringUtils.isEmpty(name)) {
                modelMap.put("message", "导入文件中第" + (i + 2) + "行的姓名为空");
                RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                return null;
            }
            if (StringUtils.isEmpty(departmentId)) {
                modelMap.put("message", "导入文件中第" + (i + 2) + "行的部门为空");
                RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                return null;
            }

            /**
             * 判断部门非空之后解析所在部门
             */
            String[] departments = departmentId.split("/");
            if (departments.length >= 2) {// 判断数组中是否有多个部门
                /*
                 * 循环查询部门是否存在
                 */
                for (int j = 0; j < departments.length; j++) {
                    String deptName = departments[j];
                    // 判断第一次进来时当前节点是不是根节点
                    if (j == 0) {
                        SysDepartment sysDepartMent = sysDepartmentService.queryRoot(deptName);
                        if (null == sysDepartMent) {// 如果不是根节点，必须从根节点写起
                            modelMap.put("message", "导入文件中第" + (i + 2) + "行的部门名称不存在，请确认组织节点是否正确。");
                            RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                            return null;
                        }
                    }
                    String nextDeptName = null;
                    if (j < departments.length - 1) {
                        nextDeptName = departments[j + 1];
                    }
                    if (!StringUtils.isEmpty(nextDeptName)) {// 如果下级节点还有部门的话，则根据上级查询下级是否存在
                        SysDepartment sysDepartment = sysDepartmentService.queryLowerIsExistence(deptName, nextDeptName);
                        if (null == sysDepartment) { // 如果下级部门不存在，则说明该机构节点名称有误
                            modelMap.put("message", "导入文件中第" + (i + 2) + "行的部门名称不存在，请确认组织节点是否正确。");
                            RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                            return null;
                        }
                        departmentId = sysDepartment.getId();// 每次查询的下级部门ID赋值给departmentId，最后一次查询的部门ID，就是人员所在部门ID
                    }
                }
            }

            /**
             * 长度校验
             */
            if (userName.length() > 50) {
                modelMap.put("message", "导入文件中第" + (i + 2) + "行的用户名长度超出范围");
                RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                return null;
            }
            if (name.length() > 50) {
                modelMap.put("message", "导入文件中第" + (i + 2) + "行的姓名长度超出范围");
                RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                return null;
            }
            if (email.length() > 50) {
                modelMap.put("message", "导入文件中第" + (i + 2) + "行的邮箱长度超出范围");
                RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                return null;
            }
            if (phone.length() > 50) {
                modelMap.put("message", "导入文件中第" + (i + 2) + "行的手机号码长度超出范围");
                RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                return null;
            }
            if (education.length() > 100) {
                modelMap.put("message", "导入文件中第" + (i + 2) + "行的学历长度超出范围");
                RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                return null;
            }
            if (wechat.length() > 50) {
                modelMap.put("message", "导入文件中第" + (i + 2) + "行的微信长度超出范围");
                RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                return null;
            }
            if (nation.length() > 50) {
                modelMap.put("message", "导入文件中第" + (i + 2) + "行的民族长度超出范围");
                RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                return null;
            }
            if (nativePlace.length() > 50) {
                modelMap.put("message", "导入文件中第" + (i + 2) + "行的籍贯长度超出范围");
                RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                return null;
            }
            if (employeeCode.length() > 32) {
                modelMap.put("message", "导入文件中第" + (i + 2) + "行的工号长度超出范围");
                RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                return null;
            }
            if (summary.length() > 255) {
                modelMap.put("message", "导入文件中第" + (i + 2) + "行的简介长度超出范围");
                RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                return null;
            }

            /**
             * 绑定实体对象
             */
            SysUser sysUser = new SysUser();
            sysUser.setUserName(userName);
            sysUser.setName(name);
            sysUser.setDepartmentId(departmentId);
            sysUser.setEmail(email);
            sysUser.setPhone(phone);
            try {
                sysUser.setBirthday(DateUtils.parseDate(birthday, DateUtils.PATTERN_YYYY_MM_DD));
            } catch (Exception e) {
                modelMap.put("message", "导入文件中第" + (i + 2) + "行的时间格式有误，请输入如下格式“1999-01-01”。");
                RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                return null;
            }
            sysUser.setEducation(education);
            sysUser.setWechat(wechat);
            sysUser.setNation(nation);
            sysUser.setNativePlace(nativePlace);
            try {
                sysUser.setJoinPartyDate(DateUtils.parseDate(joinPartyDate, DateUtils.PATTERN_YYYY_MM_DD));
            } catch (Exception e) {
                modelMap.put("message", "导入文件中第" + (i + 2) + "行的时间格式有误，请输入如下格式“1999-01-01”。");
                RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.FALSE);
                return null;
            }
            sysUser.setEmployeeCode(employeeCode);
            sysUser.setSummary(summary);
            sysUserList.add(sysUser);
        }

        /**
         * 保存实体对象
         */
        for (SysUser sysUser : sysUserList) {
            SysUser user = sysUserService.findByUserName(sysUser.getUserName());// 查询人员姓名是否存在，存在做更新操作
            if (null != user) {// 如果user不为空 则表示更新
                sysUser.setId(user.getId());
                sysUser.setState(user.getState());
                sysUser.setPassword(user.getPassword());
                sysUser.setHeadIcon(user.getHeadIcon());
                sysUserService.update(sysUser);
                updateNum++;
            } else {// 否则执行新增操作
                sysUserService.save(sysUser);
                addNum++;
            }
        }
        modelMap.put("message", "新增数据：" + addNum + "条，修改数据：" + updateNum + "条，失败：" + (dateNum - addNum - updateNum) +

        "条");
        RequestResponseUtil.putResponseStr(session, response, request, modelMap, StringConstant.TRUE);
        return null;
    }

    /**
     * 文件下载的方法，暂时未使用，留作以后使用
     * 
     * @param fileName
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("/download")
    public String downloadFile(@RequestParam("fileName") String fileName, HttpServletRequest request, HttpServletResponse response) {
        if (fileName != null) {
            String realPath = request.getSession().getServletContext().getRealPath("file/");
            File file = new File(realPath, fileName);
            if (file.exists()) {
                response.setContentType("application/force-download");// 设置强制下载不打开
                response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);// 设置文件名
                byte[] buffer = new byte[1024];
                FileInputStream fis = null;
                BufferedInputStream bis = null;
                try {
                    fis = new FileInputStream(file);
                    bis = new BufferedInputStream(fis);
                    OutputStream os = response.getOutputStream();
                    int i = bis.read(buffer);
                    while (i != -1) {
                        os.write(buffer, 0, i);
                        i = bis.read(buffer);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (bis != null) {
                        try {
                            bis.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (fis != null) {
                        try {
                            fis.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        return null;
    }

}